<template>
  <!-- 全屏加载动画 (非页面初始化的加载动画) -->
  <mxp-translate
    v-if="state"
    ref="mxpRranslateRef"
    mode="fade"
    :autoShow="true"
    :cusStyle="maskStyle"
    :cusClass="`mxp-loading-page ${cusClass}`"
    @animationEnd="onAnimationEnd"
  >
    <view class="icon-box" style="padding-bottom: 20px">
      <slot name="icon">
        <image v-if="image" :src="image" mode="aspectFill" :style="{ width: iconSize, height: iconSize }"></image>
        <mxp-icon v-else :color="props.iconColor || defThemeColor.icon" :size="iconSize" :spin="true" name="jiazai"></mxp-icon>
      </slot>
    </view>
    <slot name="text">
      <text :style="{ fontSize: textSize, color: props.textColor || defThemeColor.text3 }">
        {{ text }}
      </text>
    </slot>
  </mxp-translate>
</template>

<script lang="ts" setup>
  import { publicStyeProps } from '../mxp-tool/utils/public-props';
  import MxpIcon from '../mxp-icon/mxp-icon.vue';
  import MxpTranslate from '../mxp-translate/mxp-translate.vue';
  import { type CSSProperties, type PropType, computed, nextTick, ref, watch } from 'vue';
  import type { $AllColorStr, $SizeUnitStr } from '@/mxp-ui/mxp-tool/types/interface';
  import mxpGetSysInfoStore from '../mxp-tool/store/mxp-store-sys-info';
  import { defThemeColor } from '../mxp-tool/theme/theme';

  defineOptions({
    name: 'mxp-full-screen-loading',
  });

  const props = defineProps({
    /** 是否加载中 */
    modelValue: { type: Boolean, default: false },
    /** 提示内容 */
    text: { type: [String, Number], default: '加载中' },
    /** 字体颜色 */
    textColor: { type: String as PropType<$AllColorStr>, default: undefined },
    /** 字体大小 */
    textSize: { type: String as PropType<$SizeUnitStr>, default: '14px' },
    /** 自定义图片路径 */
    image: { type: String, default: '' },
    /** 背景色 */
    background: { type: String as PropType<$AllColorStr>, default: 'rgba(0,0,0,0.3)' },
    /** 图标大小 */
    iconSize: { type: String as PropType<$SizeUnitStr>, default: '32px' },
    /** 图标颜色 */
    iconColor: { type: String as PropType<$AllColorStr>, default: undefined },
    /** 层级 */
    zIndex: { type: Number, default: 888 },
    ...publicStyeProps,
  });
  defineSlots<{
    /** 加载中的图标 */
    icon: () => void;
    /** 自定义显示的内容 */
    text: () => void;
  }>();

  const emits = defineEmits<{
    (e: 'update:modelValue', state: boolean): void;
    (e: 'change', state: boolean): void;
  }>();
  const mxpRranslateRef = ref<InstanceType<typeof MxpTranslate> | null>(null);

  const sys = mxpGetSysInfoStore().getSysInfo();
  const maskStyle = computed<CSSProperties>(() => {
    return {
      position: 'fixed',
      top: `${sys.value.windowTop || 0}px`,
      left: 0,
      width: `${sys.value.windowWidth}px`,
      height: `${sys.value.windowHeight}px`,
      zIndex: props.zIndex,
      backgroundColor: props.background,
      display: 'flex',
      flexDirection: 'column',
      flexWrap: 'nowrap',
      alignItems: 'center',
      justifyContent: 'center',
      ...props.cusStyle,
    };
  });

  const state = ref<boolean>(props.modelValue);
  watch(
    () => props.modelValue,
    (_state) => {
      if (_state) {
        state.value = true;
      } else {
        mxpRranslateRef.value?.hide();
      }
    }
  );
  watch(
    () => state.value,
    (_state) => {
      emits('update:modelValue', _state);
      nextTick(() => {
        emits('change', _state);
      });
    }
  );

  /**
   * 动画完成
   */
  function onAnimationEnd(type: 'hide-animation' | 'show-animation') {
    if (type === 'hide-animation') {
      state.value = false;
    }
  }

  defineExpose({
    /** 手动设置状态 */
    show() {
      state.value = true;
    },
    /** 手动设置状态 */
    hide() {
      mxpRranslateRef.value?.hide();
    },
  });
</script>
